//author:kakake
class TradeController {
    public data = {
        loginright: LobsterAPI.ProgramData('loginright'),
        dbConn: LobsterAPI.ProgramData('dbConn'),
        resultdata: { data: {} }
    }
    main(funname: string) {
        var self = this;
        LobsterAPI.TrackLog("main", "--------------main-------------");
        if (funname == "wallet.pretransaction") {
            var model = JSON.parse(LobsterAPI.ProgramData("requestBody"));
            self.data.resultdata.data = self.pretransaction(model);
        }
        else if (funname == "wallet.pretransactionsuccess") {
            var model = JSON.parse(LobsterAPI.ProgramData("requestBody"));
            self.data.resultdata.data = self.pretransactionsuccess(model);
        }
        else if (funname == "wallet.transactionrefund") {
            var model = JSON.parse(LobsterAPI.ProgramData("requestBody"));
            self.data.resultdata.data = self.transactionrefund(model);
        } else if (funname == "wallet.transactionrefundsuccess") {
            LobsterAPI.TrackLog("wallet.transactionrefundsuccess", "开始");
            var model = JSON.parse(LobsterAPI.ProgramData("requestBody"));
            self.data.resultdata.data = self.transactionrefundsuccess(model);
        }
        else if (funname == "wallet.savempuser") {
            var model = JSON.parse(LobsterAPI.ProgramData("requestBody"));
            self.data.resultdata.data = self.savempuser(model);
        }
        else if (funname == "wallet.saveuser") {
            var model = JSON.parse(LobsterAPI.ProgramData("requestBody"));
            self.data.resultdata.data = self.saveuser(model);
        } else if (funname == "wallet.shareprofit") {
            var model = JSON.parse(LobsterAPI.ProgramData("requestBody"));
            self.data.resultdata.data = self.shareprofit(model);
        } else if (funname == "wallet.getaccountInfo") {
            var userId = LobsterAPI.RequestQuery("userId", "-1");
            self.data.resultdata.data = self.getaccountInfo(userId);
        } else if (funname == "wallet.gettradelist") {
            var userId = LobsterAPI.RequestQuery("userId", "-1");
            var page = LobsterAPI.RequestQuery("page", "1");
            var limit = LobsterAPI.RequestQuery("limit", "10");
            self.data.resultdata.data = self.gettradelist(page, limit, userId);
        }
        //注意：这里必须返回self.data.resultdata，不然前端收不到返回值
        return self.data.resultdata;
    }
    /**
       * 预交易
       * @param model {order:{ SubMchId:'20220505085609644323',//
              BusinessOrderNo:'123',
              OrderType:1,//业务类型 1预约挂号 2自助缴费
              PayType:1,//默认1 微信支付
              Price:4,单位分
              Body:'预约挂号',//商品描述
              Memo:'备注'//可以不填},tradelist:[{UserId:"",Amount:0,TradeMethod:0,FinancialBalance,1}] }
       */
    pretransaction(model) {
        var self = this;
        LobsterAPI.TrackLog("wallet.pretransaction", model);
        LobsterAPI.TrackLog("wallet.workid", LobsterAPI.ProgramData("workid"));
        try {
            if (model.Price <= 0)
                throw '订单金额不能小于0';
            var tradelist = JSON.parse(model.tradelist);
            if (tradelist == null && tradelist.length <= 0)
                throw '交易记录不能为空';
            tradelist.forEach(function (item) {
                var account = new AccountDao().getAccount(item.UserId);
                if (!account.AccountId)
                    throw '账号不存在';
                // if (item.FinancialBalance == 1 && account.Balance < item.Amount / 100) {
                //     throw '余额不足';
                // }
                item.AccountNo = account.AccountNo;
            });
            var tradeRecordList = new TradeRecordDao().getTradeRecord(model.BusinessOrderNo);
            if (tradeRecordList.length > 0) {
                var tradeRecord = tradeRecordList[0];
                if (tradeRecord.TradeStatus == 2)
                    throw '已经完成交易';
                if (tradeRecord.TradeStatus == 3)
                    throw '交易失败';
                model.TradeNo = tradeRecord.TradeNo;
                return self.presorder(model);
            }
            else {
                var newTradeRecordList = [];
                tradelist.forEach(function (item) {
                    newTradeRecordList.push({
                        TradeNo: new Common().generateno("tr"),
                        TradeTime: new Common().getcurrenttime(),
                        Amount: item.Amount / 100,
                        FinancialBalance: item.FinancialBalance,
                        TradeMethod: item.TradeMethod,
                        OrderNo: model.BusinessOrderNo,
                        TradeStatus: 1,
                        Memo: model.Memo,
                        UserId: item.UserId,
                        AccountNo: item.AccountNo
                    });
                });
                newTradeRecordList.forEach(function (item) {
                    var tradeRecordModel = new Model().TR_TradeRecord;
                    tradeRecordModel.WorkId = LobsterAPI.ProgramData('workid');
                    tradeRecordModel.objval = item;
                    LobsterAPI.SaveModel(self.data.dbConn, tradeRecordModel);
                });
                model.TradeNo = newTradeRecordList[0].TradeNo;
                return self.presorder(model);
            }
        }
        catch (e) {
            LobsterAPI.TrackLog("wallet.pretransaction-exception", e);
            throw e;
        }
    }
    /**
        * 预交易回调
        * @param model
        */
    pretransactionsuccess(model) {
        LobsterAPI.TrackLog("wallet.pretransactionsuccess", model);
        var self = this;
        try {
            var record = new TradeRecordDao().getTradeRecordByTradeNo(model.TradeNo);

            if (!record.TradeId)
                throw '找不到交易记录';
            if (record.TradeStatus == 2)
                throw '已经处理';
            var recordlist = new TradeRecordDao().getTradeRecord(model.BusinessOrderNo);
            recordlist.forEach(function (item) {
                var account = new AccountDao().getAccount(item.UserId);
                if (!account.AccountId)
                    throw '找不到账号'
                if (item.FinancialBalance == 1) {
                    account.Balance = parseFloat(account.Balance) + parseFloat(item.Amount);
                    account.UpdateTime = new Common().getcurrenttime();
                }
                else {
                    if (model.PayType == 3) { //余额支付
                        account.Balance = parseFloat(account.Balance) - parseFloat(item.Amount);
                        account.UpdateTime = new Common().getcurrenttime();
                    }
                }
                //更新账号余额
                var accountModel = new Model().WT_Account;
                accountModel.WorkId = item.WorkId;
                accountModel.objval = account;
                LobsterAPI.TrackLog("wallet.pretransactionsuccess-account", account);
                LobsterAPI.SaveModel(self.data.dbConn, accountModel);
                //更新交易记录状态和支付信息
                item.TradeStatus = 2;
                item.EndTime = new Common().formateDate("yyyy-MM-dd HH:mm:ss", new Date(model.TimeEnd));
                item.PaymentNo = model.TransactionId;
                item.MchId = model.MchId;
                item.TradeMethod=1;
                item.PayType=model.PayType;
                item.OrderType=model.OrderType;
                item.Balance=account.Balance;
                // item.TradeMethod = new Common().getTradeMethod(model.PayType, model.OrderType, 1);
                var tradeRecordModel = new Model().TR_TradeRecord;
                tradeRecordModel.WorkId = item.WorkId;
                tradeRecordModel.objval = item;
                LobsterAPI.SaveModel(self.data.dbConn, tradeRecordModel);

            });
            return { code: 0 };
            //预交易成功消息
            // return LobsterAPI.AppFunction.PublishCAP("wallet.wallet.pretransactionsuccess", model);
        }
        catch (e) {
            LobsterAPI.TrackLog("wallet.pretransactionsuccess-exception", e);
            throw e;
        }
    }
    /**
     * 交易退款
     * @param model 
     */
    transactionrefund(model) {
        LobsterAPI.TrackLog("wallet.transactionrefund", model);
        var self = this;
        try {
            var recordlist = new TradeRecordDao().getTradeRecord(model.BusinessOrderNo);
            if (recordlist.length == 0)
                throw '找不到源交易记录';
            if (model.RefundRealFee / 100 > recordlist[0].Amount)
                throw '退款金额不能超过订单金额';
            //退款交易记录
            var refundrecordlist = new TradeRecordDao().getTradeRecord(model.BusinessRefundNo);
            if (refundrecordlist.length == 0) {
                var newrecordlist = [];
                recordlist.forEach(item => {
                    newrecordlist.push({
                        TradeNo: new Common().generateno("tr"),
                        TradeTime: new Common().getcurrenttime(),
                        Amount: model.RefundRealFee / 100,
                        TradeMethod: model.TradeMethod,
                        OrderNo: model.BusinessRefundNo,
                        FinancialBalance: item.FinancialBalance == 1 ? 2 : 1,
                        TradeStatus: 1,
                        Memo: model.RefundDesc,
                        UserId: item.UserId,
                        AccountNo: item.AccountNo
                    })
                })
                newrecordlist.forEach(function (item) {
                    var tradeRecordModel = new Model().TR_TradeRecord;
                    tradeRecordModel.WorkId = LobsterAPI.ProgramData('workid');
                    tradeRecordModel.objval = item;
                    LobsterAPI.SaveModel(self.data.dbConn, tradeRecordModel);
                });
                model.TradeNo = newrecordlist[0].TradeNo;
                return self.refund(model);
            } else {
                if (refundrecordlist[0].TradeStatus == 2)
                    throw '已经处理';
                model.TradeNo = refundrecordlist[0].TradeNo;
                return self.refund(model);
            }
        } catch (e) {
            LobsterAPI.TrackLog("wallet.transactionrefund-exception", e);
            throw e;
        }
    }
    /**
     * 交易退款成功
     * @param model 
     */
    transactionrefundsuccess(model) {
        var self = this;
        LobsterAPI.TrackLog("wallet.transactionrefundsuccess", model);
        try {

            var record = new TradeRecordDao().getTradeRecordByTradeNo(model.TradeNo);
            if (!record.TradeId)
                throw '找不到交易记录';
            if (record.TradeStatus == 2)
                throw '已经处理';
            var recordlist = new TradeRecordDao().getTradeRecord(model.BusinessRefundNo);
            recordlist.forEach(function (item) {
                var account = new AccountDao().getAccount(item.UserId);
                if (item.FinancialBalance == 2) {
                    LobsterAPI.TrackLog("wallet.transactionrefundsuccess-accountba-am",
                        parseFloat(account.Balance) + "-" + parseFloat(item.Amount));
                    account.Balance = parseFloat(account.Balance) - parseFloat(item.Amount);
                }
                else {
                    if (model.PayType == 3) { //余额支付
                        account.Balance = parseFloat(account.Balance) + parseFloat(item.Amount);
                    }
                }
                account.UpdateTime = new Common().getcurrenttime();
                //更新账号余额
                var accountModel = new Model().WT_Account;
                accountModel.WorkId = item.WorkId;
                accountModel.objval = account;
                LobsterAPI.TrackLog("wallet.transactionrefundsuccess-saveaccount", account);
                LobsterAPI.SaveModel(self.data.dbConn, accountModel);
                //更新交易记录状态和支付信息
                item.TradeStatus = 2;
                item.EndTime = new Common().formateDate("yyyy-MM-dd HH:mm:ss", new Date(model.SuccessTime));
                item.PaymentNo = model.RefundId;
                item.MchId = model.MchId; 
                item.TradeMethod=2;
                item.PayType=model.PayType;
                item.OrderType=model.OrderType;
                item.Balance=account.Balance;
                // item.TradeMethod = new Common().getTradeMethod(model.PayType, model.OrderType, 2); 
                var tradeRecordModel = new Model().TR_TradeRecord;
                tradeRecordModel.WorkId = item.WorkId;
                tradeRecordModel.objval = item;
                LobsterAPI.SaveModel(self.data.dbConn, tradeRecordModel);

            });
            //预交易成功消息
            // return LobsterAPI.AppFunction.PublishCAP("wallet.wallet.transactionrefundsuccess", model);
            return { code: 0 };
        } catch (e) {
            LobsterAPI.TrackLog("wallet.transactionrefundsuccess-exception", e);
            throw e;
        }
    }
    /**
     * 获取交易记录
     * @param page 
     * @param limit 
     * @param userId 
     * @returns 
     */
    gettradelist(page, limit, userId) {
        return new TradeRecordDao().getTradelist(page, limit, userId);
    }
    /**
     * 查询账号信息
     * @param userId 
     */
    getaccountInfo(userId) {
        try {
            var account = new AccountDao().getAccount(userId);
            return { account: account }
        } catch (e) {
            throw e;
        }
    }
    /**
   * 预下单
   * @param model
   */
    presorder(model) {
        var response = LobsterAPI.AppFunction.CallOutService(LobsterAPI.ProgramData("appid"), "pay.pay.preorder", model);
        LobsterAPI.TrackLog("预下单", response);
        response = JSON.parse(response);
        if (response.code == 1)
            throw response.msg;
        LobsterAPI.TrackLog("预下单", 123123213);
        return response.data;
    }
    /**
     * 退款
     * @param model 
     * @returns 
     */
    refund(model) {
        var response = LobsterAPI.AppFunction.CallOutService(LobsterAPI.ProgramData("appid"), "pay.pay.refund", model);
        LobsterAPI.TrackLog("退款", response);
        response = JSON.parse(response);
        if (response.code == 1)
            throw response.msg;
        return response.data;
    }
    /**
     * 前端账号
     * @param model { UserId = user.MPUserId, NickName = user.Nickname, WorkId = workId }
     */
    savempuser(model) {
        LobsterAPI.TrackLog("wallet.verifyaccount", model);
        var self = this;
        try {
            var account = new AccountDao().getAccount(model.UserId);
            if (!account.AccountId) {
                //新建账号
                var accountNo = new Common().generateno("ac")
                var newaccount = {
                    AccountNo: accountNo,
                    Name: model.Nickname,
                    IDCard: "",
                    FrozenStatus: 0,
                    LogoutStatus: 0,
                    Total: 0,
                    FrozenBalance: 0,
                    Balance: 0,
                    DetectFlag: 1,
                    UserId: model.UserId,
                    UserType: 1,
                    WorkId: model.WorkId,
                    CreateTime: new Common().getcurrenttime()
                };
                var accountModel = new Model().WT_Account;
                accountModel.WorkId = model.WorkId;
                accountModel.objval = newaccount;
                LobsterAPI.SaveModel(self.data.dbConn, accountModel);
                //账号历史
                var newaccounthistory = {
                    AccountNo: accountNo,
                    OperationType: 5,
                    OperationTime: new Common().getcurrenttime(),
                    Memo: "新建账号",
                    WorkId: model.WorkId,
                    CreateTime: new Common().getcurrenttime(),
                }
                var accounthistoryModel = new Model().WT_AccountHistory;
                accounthistoryModel.WorkId = model.WorkId;
                accounthistoryModel.objval = accounthistoryModel;
                LobsterAPI.SaveModel(self.data.dbConn, accounthistoryModel);
            }
            return { code: 0 };
        } catch (e) {
            LobsterAPI.TrackLog("wallet.savempuser-exception", e);
            throw e;

        }
    }
    /**
     * 后台账号
     * @param model 
     */
    saveuser(model) {
        LobsterAPI.TrackLog("wallet.saveuser", model);
        var self = this;
        try {
            var account = new AccountDao().getAccount(model.UserID);
            if (!account.AccountId) {
                //新建账号
                var accountNo = new Common().generateno("ac")
                var newaccount = {
                    AccountNo: accountNo,
                    Name: model.Name,
                    IDCard: model.IDNumber,
                    FrozenStatus: 0,
                    LogoutStatus: 0,
                    Total: 0,
                    FrozenBalance: 0,
                    Balance: 0,
                    DetectFlag: 2,
                    UserId: model.UserID,
                    UserType: 1,
                    WorkId: model.WorkId,
                    CreateTime: new Common().getcurrenttime()
                };
                var accountModel = new Model().WT_Account;
                accountModel.WorkId = model.WorkId;
                accountModel.objval = newaccount;
                LobsterAPI.SaveModel(self.data.dbConn, accountModel);
                //账号历史
                var newaccounthistory = {
                    AccountNo: accountNo,
                    OperationType: 5,
                    OperationTime: new Common().getcurrenttime(),
                    Memo: "新建账号",
                    WorkId: model.WorkId,
                    CreateTime: new Common().getcurrenttime(),
                }
                var accounthistoryModel = new Model().WT_AccountHistory;
                accounthistoryModel.WorkId = model.WorkId;
                accounthistoryModel.objval = accounthistoryModel;
                LobsterAPI.SaveModel(self.data.dbConn, accounthistoryModel);
            }
            return { code: 0 };
        } catch (e) {
            LobsterAPI.TrackLog("wallet.saveuser-exception", e);
            throw e;
        }
    }
    // -1.00
    // +0.1
    // +0.2
    // +0.7
    /**
     * 分润  
     * @param model [Amount:1.00,tradelist:{UserId:6117管理员,RuleCode:""},{UserId:"医生",RuleCode:"001"},{UserId:"药师",RuleCode:"002"}]
     */
    shareprofit(model) {
        LobsterAPI.TrackLog("wallet.shareprofit", model);
        var workId = LobsterAPI.ProgramData("workid")
        var self = this;
        try {
            //判断分润数据是否存在
            var tradelist = JSON.parse(model.tradelist);
            var surplusamount = model.Amount;
            tradelist.forEach(function (item) {
                var account = new AccountDao().getAccount(item.UserId);
                if (!account.AccountId)
                    throw '账号不存在';
                if (item.RuleCode) {
                    var sharerule = new TradeRecordDao().getsharerule(item.UserId, item.RuleCode);
                    if (!sharerule.RuleId) {
                        var caclAmount = self.cacl(surplusamount, model.Amount, sharerule.RuleType, sharerule.ProfitValue);
                        if (caclAmount > 0) {
                            item.Amount = caclAmount;
                            item.FinancialBalance = 1;
                            item.sharerule = sharerule;
                            item.account = account;
                        }
                    }
                } else {
                    item.Amount = model.Amount;
                    item.FinancialBalance = 2;
                    item.account = account;
                }
            });
            if (surplusamount > 0 && surplusamount < model.Amount) {
                var filter = self.filterdata(tradelist, a => { return a.FinancialBalance == 2 });
                filter.FinancialBalance = 1;
                filter.Amount = surplusamount;
                tradelist.push(filter);
            }
            var shareNo = new Common().generateno("sh");
            tradelist.forEach(item => {
                if (item.account.AccountId > 0) {
                    //插入分润记录
                    var shareRecord = {
                        AccountNo: item.account.AccountNo,
                        ShareNo: shareNo,
                        OrderNo: model.OrderNo,
                        Amount: item.Amount,
                        Status: 2,
                        WorkId: model.workId,
                        CreateTime: new Common().getcurrenttime(),
                    };
                    var shareRecordModel = new Model().CL_ShareRecord;
                    shareRecordModel.WorkId = workId;
                    shareRecordModel.objval = shareRecord;
                    LobsterAPI.SaveModel(self.data.dbConn, shareRecordModel);
                    //插入分润规则
                    if (item.sharerule.RuleId>0) { 
                        var shareRecordRule = {
                            RecordId: shareRecordModel.objval.RecordId,
                            RuleType: item.sharerule.RuleType,
                            CalcType: item.sharerule.CalcType,
                            ProfitValue: item.sharerule.ProfitValue,
                            WorkId: workId,
                            CreateTime: new Common().getcurrenttime()
                        };
                        var shareRecordRuleModel = new Model().CL_ShareRecord;
                        shareRecordRuleModel.WorkId = workId;
                        shareRecordRuleModel.objval = shareRecordRule;
                        LobsterAPI.SaveModel(self.data.dbConn, shareRecordRuleModel);
                    }
                    //插入交易记录
                    var tradeRecord = {
                        TradeNo: new Common().generateno("tr"),
                        TradeTime: new Common().getcurrenttime(),
                        Amount: item.Amount,
                        TradeMethod:3,
                        PayType:model.PayType,
                        OrderType:model.OrderType,
                        Balance:item.account.Balance,
                        // TradeMethod: new Common().getTradeMethod(model.PayType, model.OrderType, 3),
                        OrderNo: model.OrderNo,
                        FinancialBalance: item.FinancialBalance,
                        TradeStatus: 2,
                        WorkId: workId,
                        Memo: "分润"
                    }
                    var tradeRecordModel = new Model().TR_TradeRecord;
                    tradeRecordModel.WorkId = workId;
                    tradeRecordModel.objval = tradeRecord;
                    LobsterAPI.SaveModel(self.data.dbConn, tradeRecordModel);
                    //更新账号余额
                    var account = item.account;
                    if (item.FinancialBalance == 2) {
                        account.Balance = account.Balance - item.Amount;
                    } else {
                        account.Balance = account.Balance + item.Amount;
                    }
                    var accountModel = new Model().WT_Account;
                    accountModel.WorkId = workId;
                    accountModel.objval = account;
                    LobsterAPI.SaveModel(self.data.dbConn, accountModel);
                }
            })
        } catch (e) {
            LobsterAPI.TrackLog("wallet.shareprofit-exception", e);
            throw e;
        }
    }

    filterdata(data, fun) {
        let d = [];
        data.forEach(item => {
            if (fun(item)) {
                d.push(item);
            }
        })
        return d;
    }
    /**
     * 计算分润
     * @surplusamount 剩余金额
     * @param total 总金额
     * @param ruleType 1 定额 2比例
     * @param ruleType 数值
     */
    cacl(surplusamount, total, ruleType, profitValue) {
        var caclAmount = 0;
        if (ruleType == 1) {
            caclAmount = Math.round(parseFloat(profitValue) * 100) / 100;
            caclAmount = caclAmount >= surplusamount ? surplusamount : profitValue;
            surplusamount = surplusamount - caclAmount;
        }
        else {
            caclAmount = Math.round((parseFloat(total) * parseFloat(profitValue) / 100) * 100) / 100;
            caclAmount = caclAmount >= surplusamount ? surplusamount : caclAmount;
            surplusamount = surplusamount - caclAmount;
        }
        return caclAmount;
    }
    /**
     * 撤销分润
     * @param model 
     */
    cacelshareprofit(model) {
        LobsterAPI.TrackLog("wallet.shareprofit", model);
        var self = this;
        try {
            var tradelist = JSON.parse(model.tradelist);
            tradelist.forEach(function (item) {
                var account = new AccountDao().getAccount(item.UserId);
                if (!account.AccountId)
                    throw '账号不存在';
                if (item.FinancialBalance == 1 && account.Balance < item.Amount / 100) {
                    throw '余额不足';
                }
                item.AccountNo = account.AccountNo;
            });
        } catch (e) {
            LobsterAPI.TrackLog("wallet.shareprofit-exception", e);
            throw e;
        }
    }
}